package conf

import (
	"context"
	"fmt"
	"time"

	"github.com/go-redis/redis/v8"
)

var cache *Redis

func init() {
	cache = newClient()
}

func newClient() *Redis {
	rdb := redis.NewClient(&redis.Options{
		Addr:     fmt.Sprintf("%s:%d", Env.Redis.Host, Env.Redis.Port),
		Password: Env.Redis.Password, // no password set
		DB:       Env.Redis.Db,       // use default DB
	})

	return &Redis{ctx: context.Background(), r: rdb}
}

func (that *Redis) checkClose() {
	err := that.r.Ping(that.ctx).Err()
	if err == redis.ErrClosed {
		cache = newClient()
	}
}

type Redis struct {
	ctx context.Context
	r   *redis.Client
}

func GetRedis() *Redis {
	return cache
}

func (that *Redis) Get(key string) (string, error) {
	that.checkClose()
	return that.r.Get(that.ctx, key).Result()
}

func (that *Redis) Set(key string, val interface{}, ttl time.Duration) error {
	that.checkClose()
	return that.r.Set(that.ctx, key, val, ttl).Err()
}

func (that *Redis) HMset(key string, val map[string]string) error {
	that.checkClose()
	return that.r.HSet(that.ctx, key, val).Err()
}

func (that *Redis) Hset(key, hKey, val string) error {
	that.checkClose()
	return that.r.HSet(that.ctx, key, hKey, val).Err()
}

func (that *Redis) Hget(key, hKey string) (string, error) {
	that.checkClose()
	return that.r.HGet(that.ctx, key, hKey).Result()
}

func (that *Redis) Exists(key string) int64 {
	that.checkClose()
	return that.r.Exists(that.ctx, key).Val()
}

func (that *Redis) DecrBy(key string, value int64) (int64, error) {
	that.checkClose()
	return that.r.DecrBy(that.ctx, key, value).Result()
}

func (that *Redis) IncrBy(key string, value int64) (int64, error) {
	that.checkClose()
	return that.r.IncrBy(that.ctx, key, value).Result()
}
